import json
import redis
import random
from datetime import datetime,timedelta
from flask import Blueprint,jsonify,g
from werkzeug.security import generate_password_hash
from flask_restful import Api,Resource, reqparse,marshal
from common.uitils.redis_client import RedisOper
from models import db
from models.users import *
# from common.send_sms_code import sms_code
from common.uitils.jwt_util import generate_token,check_token,_generate_token
# 使用异步任务来发送短信验证码
from celery_tasks.tasks.sms.task  import sms_code
from common.model_fields.user import *
from common.uitils.login_utils import login_required
from common.uitils.qiniu_file import qiniu_token
from common.uitils.redis_user import UserCache


user_bp = Blueprint('ubp',__name__,url_prefix='/users')
api = Api(user_bp)


class UserRegister(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username')
        parser.add_argument('password')
        parser.add_argument('nickname')
        parser.add_argument('mobile')
        parser.add_argument('confirmpassword')
        args = parser.parse_args()
        uname = args.get('username')
        pwd = args.get('password')
        nick_name = args.get('nickname')
        mobile = args.get('mobile')
        confirm_pwd = args.get('confirmpassword')

        if len(uname) > 32:
            return jsonify({'message':'账号太长', 'code': 400})
        if pwd != confirm_pwd:
            return jsonify({'message':'两次密码不一样','code':400})
        user = UserModel.query.filter_by(mobile=mobile).count()
        if user >= 1:
            return jsonify({'message': '此手机号已存在', 'code':400})

        # 写入数据库
        hash_pwd = generate_password_hash(pwd)
        try:
            user = UserModel(mobile=mobile, account=uname, password=hash_pwd,uname=nick_name)
            db.session.add(user)
            db.session.commit()
            return jsonify(message='注册成功', code=200)
        except Exception as e:
            print('register error %s'%e)
            return jsonify(message="注册失败", code=500)


class SendSMSCode(Resource):
    def post(self):
        """发送短信验证码"""
        parser = reqparse.RequestParser()
        parser.add_argument('mobile')
        args = parser.parse_args()
        mobile = args.get('mobile')
        # rest,num = sms_code(mobile)
        # 使用celery 异步发送短信验证码
        code = random.randint(10000,99999)
        print('短信验证码>>', code)
        sms_code.delay(mobile,code)
        # print("rest>>>", rest)
        # if rest:
        #     # 发送成功,把短信验证码写入到redis
        rds = redis.Redis(host="localhost",port=6379,password=123,db=2)
        rds.set('sms_%s'%mobile, code,ex=300)
        return jsonify(message="短信验证码发送成功", code=200)
        # else:
        #     return jsonify(message='短线验证码发送失败', code=500)


class UserLogin(Resource):
    rds = redis.Redis(host="localhost", port=6379, password=123, db=2)
    def post(self):
        """登录"""
        parser = reqparse.RequestParser()
        parser.add_argument('mobile')
        parser.add_argument('sms')
        args = parser.parse_args()
        mobile = args.get('mobile')
        sms_code = args.get('sms')

        if not all([mobile,sms_code]):
            return jsonify(message="登录信息不完整", code=400)
        # rds = RedisOper()
        # rds = redis.Redis(host="localhost", port=6379, password=123, db=2)

        origin_sms_code = self.rds.get('sms_%s'%mobile)
        if not origin_sms_code:
            return jsonify(message="验证码已过期",code=400)
        if sms_code != origin_sms_code.decode('utf-8'):
            return jsonify(message="验证码错误",code=500)
        # 登录成功，生成token
        try:
            user = UserModel.query.filter_by(mobile=mobile).first()
            print('user>>>',user)
            data = {
                "user": user.account,
                'id': user.uid
            }
            # expiry = timedelta(hours=2)
            # token = generate_token(data, str(expiry))
            token,refresh_token = _generate_token(data, is_refresh=False)
            print('token>>>', token)
            if token:
                data_ = {
                    'user_id': user.uid,
                    'token': token,
                    'refresh_token': refresh_token
                }
                return jsonify(message='登录成功', code=200, data=data_)
            else:
                return jsonify(message='token生成失败', code=500)

        except Exception as e:
            print("错误信息>>>", e)
            return jsonify(message='手机号未注册', code=400)


class UserInfo(Resource):
    @login_required
    def get(self,id):
        """根据用户id 获取用户信息"""
        try:
            user_cache = UserCache(id)
            if user_cache.if_user_data():
                data = user_cache.get()
                print("缓存返回")
                return jsonify(message='ok', code=200, data=data)

            user = UserModel.query.filter_by(uid=id).first()
            if user:
                user = marshal(user,user_fields)

            user_cache.add_redis(user)
            print('缓存过期，查询数据库返回')
            return jsonify(message='ok', code=200, data=user)
        except Exception as e:
            print("获取用户信息的错误>>>", e)
            return jsonify(message='服务器错误', code=500)

    @login_required
    def patch(self,id):
        parser = reqparse.RequestParser()
        parser.add_argument('nickname')
        parser.add_argument('password')
        parser.add_argument('gender')
        parser.add_argument('profile_photo')
        # parser.add_argument('id')
        args = parser.parse_args()
        nick_name = args.get('nickname')
        pwd = args.get('password')
        gender = args.get('gender')
        profile_photo = args.get('profile_photo')

        user = UserModel.query.filter_by(uid=g.user_id)
        if nick_name:
            user.update({'uname':nick_name})
        if profile_photo:
            user.update({'profile_photo':profile_photo})
        elif pwd:
            hash_pwd = generate_password_hash(pwd)
            user.update({'password': hash_pwd})
            # return jsonify(message='修改成功', code=200)
            # 在这里生成新token
            # data = {
            #     'id': g.user_id
            # }
            # token, refresh_token = _generate_token(data)
            # # 把新生成的token写入redis
            # rds = redis.Redis()
            # rds.setex("user:%s:token" % (g.user_id), 2 * 60 * 60, token)
            # return jsonify(message="修改成功", code=200,
            #                data={'token': token, 'id': g.user_id, 'refresh_token': refresh_token})
        elif gender:
            user.update({'gender': gender})
        db.session.commit()
        return jsonify(message='修改成功', code=200)

# 修改密码
# class UserUpdate(Resource):
#     def put(self):
#         parser = reqparse.RequestParser()
#         parser.add_argument('password')
#         parser.add_argument('id')
#         args = parser.parse_args()
#         pwd = args.get('password')
#         hash_pwd = generate_password_hash(pwd)
#         try:
#             UserModel.query.filter_by(uid=args.get('id')).update({'password':hash_pwd})
#             db.session.commit()
#         except Exception as e:
#             print("错误的信息>>>",e)
#             return jsonify(mssage='修改失败', code=400)
#         return jsonify(mssage='修改成功', code=200, password=pwd)


# 关注的信息
class UserRelation(Resource):
    @login_required
    def get(self):
        uid = g.user_id
        print('uid>>',uid)
        if uid:
            relation_list = Relation.query.filter_by(user_id=uid)
            print('relation_list》》》', relation_list)
            temp = []
            for i in relation_list:
                user = UserModel.query.filter_by(uid=i.foller_id).first()
                relation = marshal(user, relation_fields)
                temp.append(relation)
            print("关注>>>",temp)
            return jsonify(message="ok", code=200, data=temp)
        return jsonify(message="请重新登录", code=204)


# 跟帖
class UserCommentResource(Resource):
    @login_required
    def get(self):

        uid = g.user_id
        if uid:
            comment_list = Comment.query.filter_by(user_id=uid)
            comment = marshal(comment_list,channel_fields,envelope="data")
            print(comment)
            return jsonify(message="ok",code=200,data=comment)
        return jsonify(message="请重新登录", code=204)


# 收藏
class UserCollecctionResource(Resource):
    @login_required
    def get(self):

        uid = g.user_id
        if uid:
            collection_list = Collection.query.filter_by(user_id=uid)
            temp = []
            for i in collection_list:
                news = News.query.filter_by(nid = i.news_id).first()
                news = marshal(news, collecction_fields)
                temp.append(news)
            print("收藏》》",temp)
            return jsonify(message="ok",code=200,data=temp)
        return jsonify(message="请重新登录", code=204)


# 取消收藏
class CollectionDel(Resource):
    @login_required
    def get(self,pk):
        try:
            uid = g.user_id
            if not uid:
                return jsonify(message='请重新登录', code=204)
            Collection.query.filter_by(user_id = uid, news_id=pk).delete()
            db.session.commit()
            return jsonify(message='取消收藏', code=200)
        except Exception as e:
            print("取消收藏的错误>>", e)
            return jsonify(message='服务器错误', code=500)


class QiniuTokenResource(Resource):

    @login_required
    def get(self):
        """生成七牛云上传的token"""
        token = qiniu_token()
        return jsonify(message='ok', code=200, data={'token':token})


# 取消收藏
api.add_resource(CollectionDel, '/collection/<int:pk>')
api.add_resource(QiniuTokenResource, '/qiniu_token')
api.add_resource(UserCollecctionResource, '/star')
api.add_resource(UserCommentResource, '/comments')
api.add_resource(UserRelation, '/user_follows')
# api.add_resource(UserUpdate, '/update')
api.add_resource(UserInfo, '/info/<int:id>')
api.add_resource(UserLogin, '/login')
api.add_resource(SendSMSCode,'/send_sms_code')
api.add_resource(UserRegister,'/register')







# if cate_id:
#             channel = Channel.query.get(cate_id)
#             for i in channel.news:
#                 channel_list.append({
#                     'nid': i.nid,
#                     'title': i.title,
#                     'channel_id': i.channel_id,
#                     'cover': i.cover,
#                     'comment_count': i.comment_count,
#                     'good_count': i.good_count,
#                     'content': i.content,
#                 })






